package tools;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import uk.ac.ebi.kraken.interfaces.uniprot.DatabaseCrossReference;
import uk.ac.ebi.kraken.interfaces.uniprot.UniProtEntry;
import uk.ac.ebi.kraken.uuw.services.remoting.EntryIterator;
import uk.ac.ebi.kraken.uuw.services.remoting.EntryRetrievalService;
import uk.ac.ebi.kraken.uuw.services.remoting.Query;
import uk.ac.ebi.kraken.uuw.services.remoting.UniProtJAPI;
import uk.ac.ebi.kraken.uuw.services.remoting.UniProtQueryBuilder;
import uk.ac.ebi.kraken.uuw.services.remoting.UniProtQueryService;
import data.Protein;



public class UniprotJAPI {
	
	public Protein getENSGsAndHGNCs(String accession) {
		// Create entry retrival service
		EntryRetrievalService entryRetrievalService = UniProtJAPI.factory
				.getEntryRetrievalService();

		// Retrieve UniProt entry by its accession number
		UniProtEntry entry = (UniProtEntry) entryRetrievalService
				.getUniProtEntry(accession);

		if (entry != null)
		{
			Collection<DatabaseCrossReference> collection = entry.getDatabaseCrossReferences();
			Iterator<DatabaseCrossReference> iterator = collection.iterator();
			
			ArrayList<String> eNSGs = new ArrayList<String>();
			ArrayList<String> hgncs = new ArrayList<String>();
			while (iterator.hasNext()) {
				DatabaseCrossReference reference = iterator.next();
				if (("" + reference.getDatabase()).equals("ENSEMBL")) {
					String ensgString = "" + reference;
					int start = ensgString.indexOf("ENSG");
					if (start > 0) {
						ensgString = ensgString.substring(start, start + 15);
						eNSGs.add(ensgString);
					}
				}
				else if (("" + reference.getDatabase()).equals("HGNC")) {
					String referenceString = "" + reference;
					referenceString = referenceString.replace(";", "");
					String [] hgncSplit = referenceString.split(":");
					hgncs.add(hgncSplit[2]);
				}
			}
			Protein protein = new Protein();
			protein.ensembleIDs = eNSGs;
			protein.hgncs = hgncs;
			return protein;
		}
		return null;
	}

	public ArrayList<String> getENSGs(String accession) {
		// Create entry retrival service
		EntryRetrievalService entryRetrievalService = UniProtJAPI.factory
				.getEntryRetrievalService();

		// Retrieve UniProt entry by its accession number
		UniProtEntry entry = (UniProtEntry) entryRetrievalService
				.getUniProtEntry(accession);

		if (entry != null)
		{
			Collection<DatabaseCrossReference> collection = entry.getDatabaseCrossReferences();
			Iterator<DatabaseCrossReference> iterator = collection.iterator();
			
			ArrayList<String> eNSGs = new ArrayList<String>();
			while (iterator.hasNext()) {
				DatabaseCrossReference reference = iterator.next();
				if (("" + reference.getDatabase()).equals("ENSEMBL")) {
					String ensgString = "" + reference;
					int start = ensgString.indexOf("ENSG");
					if (start > 0) {
						ensgString = ensgString.substring(start, start + 15);
						eNSGs.add(ensgString);
					}
				}
			}
			return eNSGs;
		}
		return null;
	}
	
	public ArrayList<String> getHGNCs(String accession) {
		// Create entry retrival service
		EntryRetrievalService entryRetrievalService = UniProtJAPI.factory
				.getEntryRetrievalService();

		// Retrieve UniProt entry by its accession number
		UniProtEntry entry = (UniProtEntry) entryRetrievalService
				.getUniProtEntry(accession);

		if (entry != null)
		{
			Collection<DatabaseCrossReference> collection = entry.getDatabaseCrossReferences();
			Iterator<DatabaseCrossReference> iterator = collection.iterator();
			
			ArrayList<String> hgncs = new ArrayList<String>();
			while (iterator.hasNext()) {
				DatabaseCrossReference reference = iterator.next();
				if (("" + reference.getDatabase()).equals("HGNC")) {
					String referenceString = "" + reference;
					referenceString = referenceString.replace(";", "");
					String [] hgncSplit = referenceString.split(":");
					hgncs.add(hgncSplit[2]);
				}
			}
			return hgncs;
		}
		return null;
	}
	
	/*
	 * Return true of the accession is primary, false if secondary or deleted.
	 */
	public boolean checkIsPrimaryAccession(String accession) {
		// Create entry retrival service
		EntryRetrievalService entryRetrievalService = UniProtJAPI.factory
				.getEntryRetrievalService();
		
		// Retrieve UniProt entry by its accession number
		UniProtEntry entry = (UniProtEntry) entryRetrievalService.getUniProtEntry(accession);

		if (entry != null)
		{
			return true;
		}
		return false;
	}
	
	public String getPrimaryAccessionFromSecondary(String id) {
		// Create UniProt query service
		UniProtQueryService uniProtQueryService = UniProtJAPI.factory
				.getUniProtQueryService();

		// Example1: get entries with protein name "ClpC"
		Query query = UniProtQueryBuilder.buildProteinNameQuery("ac " + id);

		EntryIterator<UniProtEntry> entryIterator = uniProtQueryService
				.getEntryIterator(query);

		int resultSize = entryIterator.getResultSize();
		if (resultSize > 0) {
			for (UniProtEntry uniProtEntry : entryIterator) {
				return uniProtEntry.getPrimaryUniProtAccession().getValue();
			}
		}
		return null;
	}

	public static void main(String[] args) {
		UniprotJAPI uniprotJAPI = new UniprotJAPI();
		System.out.println(uniprotJAPI.checkIsPrimaryAccession("P05106"));//printary accession
		
		
		String [] secondaryAccessions = {"A0A4Z0","A0JLU0","A0JP22","A0MTT2","A0PJE5","A0T1T0","A0T1T1","A0T1T2","A1A4S7","A1L430","A1L431","A1L454","A2A278","A2A2A5"};
		for (String secondaryAccession: secondaryAccessions)
		{
			System.out.println(secondaryAccession);//secondary accession
			System.out.println(uniprotJAPI.checkIsPrimaryAccession(secondaryAccession));//secondary accession
			System.out.println(uniprotJAPI.getPrimaryAccessionFromSecondary(secondaryAccession));//secondary accession
			System.out.println();
		}
		
		System.out.println(uniprotJAPI.checkIsPrimaryAccession("A2A2C2"));//deleted accession
		System.out.println(uniprotJAPI.getPrimaryAccessionFromSecondary("A2A2C2"));//deleted accession
		
		
		
	}
}
